
#import direct.ffi.panda3d
import direct.directbase.DirectStart

from panda3d.core import Filename
from panda3d.core import Point3
from panda3d.core import GeomVertexReader
from panda3d.physx import PhysxKitchen
from panda3d.physx import PhysxTriangleMeshDesc
from panda3d.physx import PhysxManager




def processNP(modelNP):
  vertices = []
  triangles = []

  for geomNP in modelNP.findAllMatches('**/+GeomNode'):
    geomNode = geomNP.node()
    if "Mesh" in geomNode.getName():
        ts = geomNode.getTransform()
        for geom in geomNode.getGeoms():
          processVertices(geom, vertices, ts)
          processIndices(geom, triangles)

  return vertices, triangles

def processVertices(geom, vertices, ts):
  m = ts.getMat().getUpper3()
  p = ts.getMat().getRow3(3)

  vdata = geom.getVertexData()
  reader = GeomVertexReader(vdata, 'vertex')
  while not reader.isAtEnd():
    v = reader.getData3f()
    v = m.xform(v) + p
    vertices.append(Point3(v))

def processIndices(geom, triangles):
  for prim in geom.getPrimitives():
    prim = prim.decompose()
    for p in range(prim.getNumPrimitives()):
      s = prim.getPrimitiveStart(p)
      e = prim.getPrimitiveEnd(p)

      assert ((e - s) % 3 == 0)

      triangle = []
      for i in range(s, e):
        vi = prim.getVertex(i)
        triangle.append(vi)
      triangles.append(triangle)





def cookModel(baseName):
  eggName = '%s.egg' % baseName
  meshName = '%s.nxb' % baseName

  np = loader.loadModel(eggName)
  points, triangles = processNP(np)

  PhysxManager.getGlobalPtr()

  meshDesc = PhysxTriangleMeshDesc()
  meshDesc.setNumVertices(len(points))
  meshDesc.setNumTriangles(len(triangles))

  for idx, point in enumerate(points):
    meshDesc.setVertex(idx, point)

  for idx, (i0, i1, i2) in enumerate(triangles):
    meshDesc.setTriangle(idx, i0, i1, i2)

  kitchen = PhysxKitchen()
  print kitchen.cookTriangleMesh(meshDesc, Filename(meshName))


#def cookModel2(baseName):
#  eggName = 'models/%s.egg' % baseName
#  meshName = 'models/%s.nxb' % baseName

#  np = loader.loadModel(eggName)

#  PhysxManager.getGlobalPtr()

#  meshDesc = PhysxTriangleMeshDesc()
#  meshDesc.setFromNodePath(np)

#  kitchen = PhysxKitchen()
#  kitchen.cookTriangleMesh(meshDesc, Filename(meshName))



if __name__ == '__main__':
  cookModel('assault')

